---
id: 优化构建速度
title: 优化-构建速度
---

## 优化 babel-loader (可用于生产环境)

```js
// webpack.config.js
{
    test: /\.js$/,
    use: ['babel-loader?cacheDirectory'], // 开启缓存
    include: path.resolve(__dirname,'src') // 明确范围
}
```

## IgnorePlugin(可用于生产环境)

## noParse(可用于生产环境)
- 提高构建速度
- 直接通知webpack忽略较大的库
- 被忽略的库不能有imporit, require, define的引入方式
```js
// webpack.config.js
module:{
  noParse: /lodash/
}
```
## thread-loader 多进程打包(推荐使用)
yarn add -D thread-loader

```js
module.exports = {
  module: {
    rules: [{
      test: /\.js$/,
      use: [
        'thread-loader',
        'babel-loader',
        'eslint-loader'
      ],
    }, ],
  },
};
```

Thread-loader 是 Webpack 官方推荐的并行处理组件，实现与使用都非常简单，但它也存在一些问题：

Loader 中不能调用 emitAsset 等接口，这会导致 style-loader 这一类 Loader 无法正常工作，解决方案是将这类组件放置在 thread-loader 之前，如 ['style-loader', 'thread-loader', 'css-loader']
Loader 中不能获取 compilation、compiler 等实例对象，也无法获取 Webpack 配置
这会导致一些 Loader 无法与 Thread-loader 共同使用，读者需要仔细加以甄别、测试。
## happyPack 多进程打包(可用于生产环境)

- JS 单线程，开启多进程打包
- 提高构建速度（特别是多核 CPU)
  `npm i happypack -D`

```js
// webpack.config.js
const HappyPack = require('happypack');
// loader
{
    test: /\.js$/,
    use: ['happypack/loader?id=babel'], // 把对.js 文件的处理转交给 id 为babel 的HappyPack 实例
    include: path.resolve(__dirname,'src') // 明确范围
}

//
plugins: [
    new HappyPack({
        id: 'babel', // 用唯一的标识符 id 来代表当前的HappyPack 是用来处理一类特定的文件类型。
        loaders: ['babel-loader?cacheDirectory'] // 1/ 如何处理js 文件，用法和 Loader 配置中一样。
    })
]
```

## ParallelUglifyPlugin 多进程压缩 JS(可用于生产环境)

- webpack 内置 Uglify 工具压缩 JS
- JS 单线程 ，开启多进程压缩更快
- 和 happyPack 相同

```js
// webpack.config.js
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
// plugin
[
  //使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
  new ParallelUglifyPlugin({
    uglifyJS: {
      output: {
        beautify: false, // 最紧凑的输出
        comments: false, // 删除所有的注释
      },
      compress: {
        drop_console:true, // 删除所有的console语句，可以兼容ie浏览器
        collapse_vars: true, // 内嵌定义了但是只用到一次的变量
        reduce_vars: true,// 提取出出现多次但是没有定义成变量去引用的静态值
      },
    },
  }),
];
```

:::tip
- 项目较大，打包较慢，开启多进程能提高速度
- 项目较小，打包很快，开启多进程会降低速度（进程开销）
:::
## 自动刷新
自动刷新：整个网页全部刷新，速度较慢,状态会丟失
## 热更新
热更新：新代码生效，网页不刷新，状态不丢失
## DllPlugin 动态链接库插件(不建议用于生产环境)

作用： 前端框架如 vue React，体积大，构建慢，且无需经常升级版本的包，利用DllPlugin构建一次即可，后面不用每次都重新构建
- webpack 已内置 DlIPlugin 支持
- DllPlugin 打包出 dll 文件
- DllReferencePlugin 使用 dll 文件

### 配置 

```js 
// webpack.dll.js
const DllPlugin= require('webpack/lib/DllPlugin')

module.exports = {
  mode: 'development',
  entry: {
    react: ['react', 'react-dom'] // 把 React 相关模块的放到一个单独的动态链接库
  },
  output: {
    // 输出的动态链接库的文件名称，[name] 代表当前动态链接库的名称，
    // 也就是entry 中配置的react 和polyfill
    filename: '[name].dll.js',
    path: 'dist/', // 输出的文件都放到 dist 目录下
    // 存放动态链接库的全局变量名称，例如对应react 来说就是_d1l_react
    // 之所以在前面加上_dll_ 是为了防止全局变量冲突
    library: '_dll_[name]'
  },
  plugins: [
    //接入 DllPlugin
    new DllPlugin({
      // 动态链接库的全局变量名称，需要和 output.library 中保持一致
      // 该字段的值也就是输出的manifest.json 文件 中name 字段的值
      // 例如react.manifest.json 中就有"name"："dll react"
      name: '_dll_[name]',
      // 描述动态链接库的 manifest. json 文件输出时的文件名称
      path: path.join('dist','[name].manifest.json')
    })
  ]
}

```

```js 
// webpack.config.js
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')
plugins: [
  new webpack.DefinePlugin({
    // window. ENV ="production"
    ENV: JSON.stringify('development')
  }),
// 第三，告诉 webpack 使用了哪些动态链接库
  new DllReferencePlugin({
    // 描述react 动态链接库的文件内容
    manifest: require(path.join('dist', 'react.manifest.json'))
  })
]

```



https://zhuanlan.zhihu.com/p/425076452